package com.olap.starter.common.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Scanner;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class AESCRUDUtils {

    private static final String KEY = "liuzhououlaipu66";
    private static final String ALGORITHM = "AES";

    private static final String AES_CBC = "AES/CBC/PKCS5Padding";

    /**
     * 加密流程：GZIP压缩 → AES加密 → Base64输出
     *
     * @param data 待加密对象
     */
    public static String encryptWithCompress(Object data) {
        try {
            // Step1：JSON序列化
            String jsonStr = new ObjectMapper().writeValueAsString(data);

            // Step2：GZIP压缩
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try (GZIPOutputStream gzip = new GZIPOutputStream(bos)) {
                {
                    gzip.write(jsonStr.getBytes(StandardCharsets.UTF_8));
                }
            }
            byte[] compressed = bos.toByteArray();

            // Step3：AES加密
            Cipher cipher = Cipher.getInstance(AES_CBC);
            SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
            byte[] ivBytes = new byte[16];
            SecureRandom.getInstanceStrong().nextBytes(ivBytes);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivBytes));
            byte[] encrypted = cipher.doFinal(compressed);

            // Step4：拼接IV+密文
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            output.write(ivBytes);
            output.write(encrypted);
            return Base64.encodeBase64String(output.toByteArray());
        } catch (Exception e) {
            throw new RuntimeException("加密异常！" + e.getMessage());
        }

    }

    /**
     * 解密流程：Base64解码 → AES解密 → GZIP解压
     *
     * @param encryptedBase64 加密字符串
     */
    public static String decryptWithDecompress(String encryptedBase64)  {

        try {
            byte[] fullData = Base64.decodeBase64(encryptedBase64);
            byte[] iv = Arrays.copyOfRange(fullData, 0, 16);
            byte[] cipherText = Arrays.copyOfRange(fullData, 16, fullData.length);

            // AES解密
            Cipher cipher = Cipher.getInstance(AES_CBC);
            SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes(), ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
            byte[] decrypted = cipher.doFinal(cipherText);

            // GZIP解压
            ByteArrayInputStream bis = new ByteArrayInputStream(decrypted);
            try (GZIPInputStream gzip = new GZIPInputStream(bis);
                 Scanner scanner = new Scanner(gzip, StandardCharsets.UTF_8.name())) {
                {
                    return scanner.useDelimiter("\\A").next();
                }
            }
        }catch (Exception e){
            throw new RuntimeException("解密异常！" + e.getMessage());
        }
    }

    public static void main(String[] args) {
        try {
            String data = "{\"message\": \"Hello, AES!\"}";
            String encrypted = encryptWithCompress(data);
            System.out.println("Encrypted: " + encrypted);
            String decrypted = decryptWithDecompress("1PXCKdGn+tGSnmNGGom27m9abWf/XMwszWHlwMpNImJqnqwmuh2S9XgpaNU7S0BbsyTCkuGyjnfB2kqpYsu5/5U6ln6MB1sKk4LjgYsRJU86ymKc/rtT/Er+rVOcMf/acG0UJykAmSUcnJP5AR8XYYn1c7Y+1vf61XoVJfVjJZK6FdOQRFwhCJHsz3tSOELXerZCL5E0cFRiimFr07FuMpUh/C8t6FfwIZjgdv5451Nv8vWjzNGu5aa7yzkMS4jJrHX2f5HJ73etSK8CvkvfPg==");
            System.out.println("Decrypted: " + decrypted);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
